#!/usr/bin/env bash
__DEFCONFIGS=./koji_builder_deployment.conf
source $__DEFCONFIGS

# ${1} is builder number
# the full builder name is ${BUILDER_NAME_PREFIX}_${1}
# os image is ${BUILDER_OS_PREFIX}_${1}.raw
prepare_libvirt_xml ()
{
	if [ -f ${TMP_DIR}/${BUILDER_NAME_PREFIX}_${1}.xml ]
	then
		echo "[SKIP]: libvirt XML existed: ${TMP_DIR}/${BUILDER_NAME_PREFIX}_${1}.xml."
		return 0
	fi
	echo "[DEPLOY]: libvirt XML for ${BUILDER_NAME_PREFIX}_${1}"
	cp -vf ${KOJI_BUILDER_XML_TEMPLATE} \
	${TMP_DIR}/${BUILDER_NAME_PREFIX}_${1}.xml
#	echo -e " builder_name: ${BUILDER_NAME_PREFIX}_${1}\n" \
#	"image_builder_memory: ${BUILDER_MEMORY}\n" \
#	"opensbi_bin: ${OPENSBI_PATH}\n" \
#	"uboot_bin: ${UBOOT_PATH}\n" \
#	"image_builder_OS: ${BUILDER_OS_PREFIX}_${1}.raw\n" \
#	"image_builder_data: ${BUILDER_DATA_PREFIX}_${1}.data.raw\n"
	sed -i \
	-e "s|@@builder_name@@|${BUILDER_NAME_PREFIX}_${1}|g" \
	-e "s|@@image_builder_memory@@|${BUILDER_MEMORY}|g" \
	-e "s|@@opensbi_bin@@|${OPENSBI_PATH}|g" \
	-e "s|@@uboot_bin@@|${UBOOT_PATH}|g" \
	-e "s|@@image_builder_OS@@|${STORAGE_POOL}/${BUILDER_OS_PREFIX}_${1}.raw|g" \
	-e "s|@@image_builder_data@@|${STORAGE_POOL}/${BUILDER_DATA_PREFIX}_${1}.data.raw|g" \
	${TMP_DIR}/${BUILDER_NAME_PREFIX}_${1}.xml
}

prepare_kojid_data ()
{
	echo "[PREPARING]: kojid data for master tape"
	mkdir -p ${TMP_DATA_DIR}

	cp -vrf ${TEMPLATE_DIR}/kojid \
	${TMP_DATA_DIR}/

	sed -i \
	-e "s|@@KOJID_MAXJOBS@@|${KOJID_MAXJOBS}|g"	\
	-e "s|@@KOJID_MINSPACE@@|${KOJID_MINSPACE}|g"	\
	-e "s|@@KOJID_RPMBUILD_TIMEOUT@@|${KOJID_RPMBUILD_TIMEOUT}|g"	\
	-e "s|@@KOJID_SERVER@@|${KOJID_SERVER}|g"	\
	-e "s|@@KOJID_TOPURL@@|${KOJID_TOPURL}|g"	\
	-e "s|@@KOJID_ALLOWED_SCMS@@|${KOJID_ALLOWED_SCMS}|g"	\
	-e "s|@@KOJID_SMTPHOST@@|${KOJID_SMTPHOST}|g"	\
	-e "s|@@KOJID_FROM_ADDR@@|${KOJID_FROM_ADDR}|g"	\
	-e "s|@@KOJID_CERT@@|${KOJID_CERT}|g"	\
	-e "s|@@KOJID_SERVERCA@@|${KOJID_SERVERCA}|g"	\
        ${TMP_DATA_DIR}/kojid/kojid.conf

	mkdir -p ${TMP_DATA_DIR}/anchors ${TMP_DATA_DIR}/mock
	cp -vf ${KOJID_CA_CERT_PATH} \
	${TMP_DATA_DIR}/kojid/serverca.crt
	cp -vf ${KOJID_CA_CERT_PATH} \
	${TMP_DATA_DIR}/anchors/serverca.crt
}

update_fstab_file ()
{
	echo "[UPDATING]: fstab file for builder server"
	mkdir -p ${TMP_DATA_DIR}

	cp -vrf ${TEMPLATE_DIR}/fstab \
	${TMP_DATA_DIR}/

	sed -i \
	-e "s|##POOL_UUID##|${1}|g"	\
        ${TMP_DATA_DIR}/fstab

	sudo cat -vf ${TMP_DATA_DIR}/fstab >> /etc/fstab
}

#please fix it for your own server
storage_configuration ()
{
            sudo systemctl enable --now stratisd
            sudo stratis pool create Storage /dev/sdb
            sleep 1
            POOL_UUID=`sudo stratis pool list | awk 'NR==2{print $12}'`; update_fstab_file ${POOL_UUID}
            sudo stratis filesystem create Storage home
            sudo stratis filesystem create Storage libvirt-images
            sleep 1
            sudo mount -a
            sleep 1
} 

account_init ()
{
	while read line
	do
	    __GN=`echo $line | awk '{print $1}'`
	    __UN=$__GN
	    __GID=`echo $line | awk '{print $3}'`
	    __UID=`echo $line | awk '{print $2}'`
            sudo groupadd -g ${__GID} ${__GN} || break
	    sudo useradd -g ${__GID} -u ${__UID} ${__UN} || break
	    sudo usermod -G wheel ${__UN}
	    #sudo gpasswd -a ${__UN} wheel
	    sudo mkdir -p /home/${__UN}/.ssh
	    sudo cp ${USER_KEY_DIR}/${__UN} /home/${__UN}/.ssh/authorized_keys
	    sudo chown -R ${__UN}:${__GN} /home/${__UN}/.ssh
	    sudo chmod 600 /home/${__UN}/.ssh/authorized_keys
	done < ${USER_LIST_CONF}
}

#if we can't start vm with error:
#error: error creating bridge interface virbr0: File exists
reset_libvirt_net_default ()
{
	__NET_NAME=default
	__NET_BR=virbr0
	__TEMP_XML=net_${__NET_NAME}_${__NET_BR}.xml

	sudo systemctl stop libvirtd

	sudo virsh net-dumpxml --network ${__NET_NAME} > ${__TEMP_XML}
	sudo virsh net-undefine --network ${__NET_NAME}

	sudo ip link delete ${__NET_BR}
	sudo virsh net-define ${__TEMP_XML}

	sudo virsh net-autostart --network ${__NET_NAME}
	sudo virsh net-start --network ${__NET_NAME}

	sudo systemctl start libvirtd

	sudo virsh net-list --all
}

#the output binary is ${KOJI_BUILDER_IMAGE_PREFIX}.raw
#generate the master os image
decompress_os_image ()
{
	echo "[PREPARING]: OS Image master tape"
	if [ ! -f $TMP_DIR/$KOJI_BUILDER_OS_IMAGE_TARBALL ]
	then
		if [ ! -n $KOJI_BUILDER_OS_IMAGE_URL ]
		then
			echo ERROR: Missing Koji Builder OS Image and URL!
			exit 1
		else
			wget --progress=bar --show-progress\
			--no-check-certificate \
			--output-file=${TMP_DIR}/wget.log \
			-O ${TMP_DIR}/$KOJI_BUILDER_OS_IMAGE_TARBALL \
			$KOJI_BUILDER_OS_IMAGE_URL
		fi
	fi
	${KOJI_BUILDER_OS_IMAGE_DECOMPRESS} -f -k -d --verbose ${TMP_DIR}/$KOJI_BUILDER_OS_IMAGE_TARBALL
}

#generate the master data image
generate_data_image ()
{
	if [  ! -b ${KOJI_BUILDER_DATA_NDB_DEV} ]
	then
		echo ERROR: Missing ${KOJI_BUILDER_DATA_NDB_DEV}.
		echo "Note: please do 'sudo modprobe nbd' first".
		exit 1
	fi

	if [  ! -d ${TMP_DATA_DIR} ]
	then
		echo "ERROR: Missing kojid conf file for master tape."
		exit 1
	fi
	echo "[PREPARING]: Generate Data Image master tape"
	[[ -d $KOJI_BUILDER_DATA_MNT_DIR ]] || \
	mkdir -p $KOJI_BUILDER_DATA_MNT_DIR

	qemu-img create \
	-f ${KOJI_BUILDER_DATA_FORMAT} \
	${TMP_DIR}/${KOJI_BUILDER_DATA_MS} \
	${KOJI_BUILDER_DATA_SIZE} || exit 1

	sgdisk --clear -g \
	--new=1:${KOJI_BUILDER_DATA_PART1_START}:${KOJI_BUILDER_DATA_PART1_END} \
	--change-name=1:"${KOJI_BUILDER_DATA_PART1_NAME}" \
	--typecode=1:${KOJI_BUILDER_DATA_PART1_TYPE} \
	${TMP_DIR}/${KOJI_BUILDER_DATA_MS} || exit 1

	sudo qemu-nbd \
	-f ${KOJI_BUILDER_DATA_FORMAT} \
	--connect  ${KOJI_BUILDER_DATA_NDB_DEV} \
	${TMP_DIR}/${KOJI_BUILDER_DATA_MS} || exit 1

	sudo mkfs.ext4 ${KOJI_BUILDER_DATA_NDB_DEV}p1
#	sudo growpart ${NDB_DEV} 1
#	sudo resize2fs ${NDB_DEV}p1
	sudo fsck -vf ${KOJI_BUILDER_DATA_NDB_DEV}p1
	
	sudo mount -v ${KOJI_BUILDER_DATA_NDB_DEV}p1 \
	${KOJI_BUILDER_DATA_MNT_DIR} || exit 1

	sudo cp -rv ${TMP_DATA_DIR}/* ${KOJI_BUILDER_DATA_MNT_DIR}
	sudo chown -R root:root ${KOJI_BUILDER_DATA_MNT_DIR}/kojid
	sudo chown -R root:root ${KOJI_BUILDER_DATA_MNT_DIR}/anchors
	sync
	sudo tree ${KOJI_BUILDER_DATA_MNT_DIR}

	sudo umount ${KOJI_BUILDER_DATA_MNT_DIR}
	sudo qemu-nbd --disconnect ${KOJI_BUILDER_DATA_NDB_DEV}
}

generate_master_tape ()
{
	echo "=========[PREPARING]: Generating Master Images========="
	if [  ! -f ${TMP_DIR}/${KOJI_BUILDER_DATA_MS} ]
	then
		prepare_kojid_data
		generate_data_image
	else
		echo "[SKIP]: master data image existed."
	fi

	if [  ! -f ${TMP_DIR}/${KOJI_BUILDER_OS_IMAGE_MS} ]
	then
		decompress_os_image
	else
		echo "[SKIP]: master os image existed."
	fi

	echo "Master Tapes:"
	ls -1 ${TMP_DIR}/*.raw
	echo "====================================="
	KOJI_BUILDER_MASTER_TAPE=Y
}

copy_from_master_tape ()
{
	[[ -d $STORAGE_POOL ]] || \
	mkdir -p $STORAGE_POOL
	if [  ! -f ${TMP_DIR}/${KOJI_BUILDER_DATA_MS} ]
	then
		echo ERROR: Missing master data image.
		exit 1
	fi

	if [  ! -f ${TMP_DIR}/${KOJI_BUILDER_OS_IMAGE_MS} ]
	then
		echo ERROR: Missing master os image.
		exit 1
	fi
	cp -v ${TMP_DIR}/${KOJI_BUILDER_OS_IMAGE_MS} \
	${STORAGE_POOL}/${KOJI_BUILDER_IMAGE_PREFIX}_${1}.raw || \
	exit 1
	echo OS Image: ${STORAGE_POOL}/${KOJI_BUILDER_IMAGE_PREFIX}_${1}.raw
	cp -v ${TMP_DIR}/${KOJI_BUILDER_DATA_MS} \
	${STORAGE_POOL}/${KOJI_BUILDER_IMAGE_PREFIX}_${1}.data.${KOJI_BUILDER_DATA_FORMAT} || \
	exit 1
	echo Data Image: ${STORAGE_POOL}/${KOJI_BUILDER_IMAGE_PREFIX}_${1}.data.${KOJI_BUILDER_DATA_FORMAT}
}

install_pem_to_data_image ()
{
	if [  ! -f ${STORAGE_POOL}/${KOJI_BUILDER_IMAGE_PREFIX}_${1}.data.${KOJI_BUILDER_DATA_FORMAT} ]
	then
		echo "ERROR: Missing ${1} data image."
		exit 1
	fi

	if [  ! -b ${KOJI_BUILDER_DATA_NDB_DEV} ]
	then
		echo ERROR: Missing ${KOJI_BUILDER_DATA_NDB_DEV}.
		echo "Note: please do 'sudo modprobe nbd' first".
		exit 1
	fi

	if [  ! -f ${KOJID_PEMS_DIR}/${KOJID_PEMS_PREFIX}${1}${KOJID_PEMS_SUBFIX}.pem ]
	then
		echo "ERROR: Missing the pem file for ${1}."
		exit 1
	fi

	[[ -d $KOJI_BUILDER_DATA_MNT_DIR ]] || \
	mkdir -p $KOJI_BUILDER_DATA_MNT_DIR

	sudo qemu-nbd \
	-f ${KOJI_BUILDER_DATA_FORMAT} \
	--connect  ${KOJI_BUILDER_DATA_NDB_DEV} \
	${STORAGE_POOL}/${KOJI_BUILDER_IMAGE_PREFIX}_${1}.data.${KOJI_BUILDER_DATA_FORMAT}
	sleep 1
	sudo mount -v ${KOJI_BUILDER_DATA_NDB_DEV}p1 ${KOJI_BUILDER_DATA_MNT_DIR}

	sudo cp -v ${KOJID_PEMS_DIR}/${KOJID_PEMS_PREFIX}${1}${KOJID_PEMS_SUBFIX}.pem \
	${KOJI_BUILDER_DATA_MNT_DIR}/kojid/client.crt
	sudo chown root:root ${KOJI_BUILDER_DATA_MNT_DIR}/kojid/client.crt
	sync
	sudo tree ${KOJI_BUILDER_DATA_MNT_DIR}
	echo "Install pem to data Image: ${KOJID_PEMS_DIR}/${KOJID_PEMS_PREFIX}${1}${KOJID_PEMS_SUBFIX}.pem"
	sudo umount ${KOJI_BUILDER_DATA_MNT_DIR}
	sudo qemu-nbd --disconnect ${KOJI_BUILDER_DATA_NDB_DEV}
}

generate_builder_images ()
{
	if [ ! -n "${KOJI_BUILDER_MASTER_TAPE}" ]
	then
		generate_master_tape
	fi
	if [ -n "${1}" ]
	then
		echo "=========[DEPLOY]: {KOJI_BUILDER_IMAGE_PREFIX}_${1}========="
	else
		echo "ERROR: Missing builder Number!"
		return 1
	fi
	copy_from_master_tape ${1}
	install_pem_to_data_image ${1}
	echo "====================================="
}

define_builder ()
{
	echo "[DEPLOY]: Define ${TMP_DIR}/${BUILDER_NAME_PREFIX}_${1}.xml"
	sudo virsh define ${TMP_DIR}/${BUILDER_NAME_PREFIX}_${1}.xml
}

#much slow then copy and define
clone_builder ()
{
	sudo virt-clone \
	--connect=qemu:///system \
	-o ${BUILDER_NAME_PREFIX}_${1} \
	-n ${BUILDER_NAME_PREFIX}_${2} \
	-f ${STORAGE_POOL}/${BUILDER_NAME_PREFIX}_${2}.raw \
	-f ${STORAGE_POOL}/${BUILDER_NAME_PREFIX}_${2}.data.raw
}

deploy_firmware ()
{
	echo "=========[DEPLOY]: Firmware ========="
	if [  ! -f ${OPENSBI_PATH} ]
	then
		sudo wget --progress=bar --show-progress\
		--no-check-certificate \
		--output-file=${TMP_DIR}/opensbi_wget.log \
		-O ${OPENSBI_PATH} \
		$KOJI_BUILDER_FW_URL && \
		echo "[DEPLOY]: download opensbi from $KOJI_BUILDER_FW_URL to ${OPENSBI_PATH}"
	else
		echo "[SKIP]: opensbi existed: ${OPENSBI_PATH}"
	fi
	if [  ! -f ${UBOOT_PATH} ]
	then
		sudo wget --progress=bar --show-progress\
		--no-check-certificate \
		--output-file=${TMP_DIR}/uboot_wget.log \
		-O ${UBOOT_PATH} \
		$KOJI_BUILDER_UBOOT_URL && \
		echo "[DEPLOY]: download U-boot from $KOJI_BUILDER_UBOOT_URL to ${UBOOT_PATH}"
	else
		echo "[SKIP]: U-boot existed: ${UBOOT_PATH}"
	fi
	echo "====================================="
}

start_builder ()
{
	sudo virsh start ${BUILDER_NAME_PREFIX}_${1}
	sudo virsh autostart ${BUILDER_NAME_PREFIX}_${1}
}

fix_data_image ()
{
	if [  ! -f ${STORAGE_POOL}/${KOJI_BUILDER_IMAGE_PREFIX}_${1}.data.${KOJI_BUILDER_DATA_FORMAT} ]
	then
		echo "ERROR: Missing ${1} data image."
		exit 1
	fi

	if [  ! -b ${KOJI_BUILDER_DATA_NDB_DEV} ]
	then
		echo ERROR: Missing ${KOJI_BUILDER_DATA_NDB_DEV}.
		echo "Note: please do 'sudo modprobe nbd' first".
		exit 1
	fi

	[[ -d $KOJI_BUILDER_DATA_MNT_DIR ]] || \
	mkdir -p $KOJI_BUILDER_DATA_MNT_DIR

	sudo virsh destroy ${BUILDER_NAME_PREFIX}_${1}

	sudo qemu-nbd \
	-f ${KOJI_BUILDER_DATA_FORMAT} \
	--connect  ${KOJI_BUILDER_DATA_NDB_DEV} \
	${STORAGE_POOL}/${KOJI_BUILDER_IMAGE_PREFIX}_${1}.data.${KOJI_BUILDER_DATA_FORMAT}
	sleep 1
	sudo mount -v ${KOJI_BUILDER_DATA_NDB_DEV}p1 ${KOJI_BUILDER_DATA_MNT_DIR}

	./fix_data_image.sh ${KOJI_BUILDER_DATA_MNT_DIR} || exit 1

	sync
	echo "Fixed data Image: ${STORAGE_POOL}/${KOJI_BUILDER_IMAGE_PREFIX}_${1}.data.${KOJI_BUILDER_DATA_FORMAT}"
	sudo umount ${KOJI_BUILDER_DATA_MNT_DIR}
	sudo qemu-nbd --disconnect ${KOJI_BUILDER_DATA_NDB_DEV}

	start_builder ${1}
}

#DEBUG: func test
#prepare_libvirt_xml ${1}
#decompress_os_image
#prepare_kojid_data
#generate_data_image
#generate_master_tape
#generate_builder_images ${1}
#define_builder ${1}
#sudo virsh undefine ${BUILDER_NAME_PREFIX}_${1}
#clone_builder ${1} ${2}
#start_builder ${2}

#generate_builder_images ${2}
#prepare_libvirt_xml ${2}
#define_builder ${2}
#install_pem_to_data_image ${2}
#start_builder ${2}

[[ -d $TMP_DIR ]] || mkdir -p $TMP_DIR

#C, config file
#s, start
#p, step
#e, end
while getopts "C:s:p:e:w:fi" arg #选项后面的冒号表示该选项需要参数
do
    case $arg in
        C)
            source $OPTARG
            ;;
        s)
            BUILDER_START_NUM=$OPTARG
            ;;
        p)
            BUILDER_STEP=$OPTARG
            ;;
        e)
            BUILDER_END_NUM=$OPTARG
            ;;
        w)
            BUILDER_NUM_WIDTH=$OPTARG
            ;;
        f)
            BUILDER_FIX=Y
            ;;
        i)
            echo "server init"
            #sudo mkdir -p /mnt/nfs
            #sudo yum install -y $DEPENDENCY_PKG
            #storage_configuration
            sudo semanage fcontext -a -t virt_image_t ${STORAGE_POOL}
            sudo restorecon -R ${STORAGE_POOL}
            sudo systemctl enable --now systemd-resolved
            ls -l /etc/resolv.conf
            sudo echo "$BUILDER_HOSTS" >> /etc/hosts
            sudo systemctl enable --now libvirtd
            sudo virsh net-start default
            sudo firewall-cmd --add-service=https --zone=libvirt  --permanent
            sudo firewall-cmd --add-service=http --zone=libvirt  --permanent
            sudo systemctl restart firewalld
            account_init
            exit 0
            ;;
        ?)  #当有不认识的选项的时候arg为?
            echo "unkonw argument"
            exit 1
        ;;
    esac
done
  
#echo 处理完参数后的 OPTIND：$OPTIND
#echo 移除已处理参数个数：$((OPTIND-1))
shift $((OPTIND-1))
#echo 参数索引位置：$OPTIND
#echo 准备处理余下的参数：
#echo "Other Params: $@"

deploy_firmware

BUILDER_LIST=`seq -f "%0${BUILDER_NUM_WIDTH}g" $BUILDER_START_NUM $BUILDER_STEP $BUILDER_END_NUM`
#echo $BUILDER_LIST

sudo modprobe nbd

for builder_num in $BUILDER_LIST
do
	if [ -n "${BUILDER_FIX}" ]
	then
		fix_data_image ${builder_num} || exit 1
	else
		generate_builder_images ${builder_num}
		prepare_libvirt_xml ${builder_num}
		define_builder ${builder_num} || exit 1
		start_builder ${builder_num} || exit 1
	fi
	sleep 1

done

sudo modprobe -r nbd
